package com.louis.buddhist.widget.dialog;

import android.Manifest;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.DialogFragment;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.FileProvider;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.ProgressBar;
import android.widget.Toast;

import com.louis.buddhist.BuildConfig;
import com.louis.buddhist.R;
import com.louis.buddhist.data.C;
import com.louis.buddhist.data.entity.Book;
import com.louis.buddhist.db.BookDaoOpen;
import com.louis.buddhist.ui.activity.ReadActivity;
import com.louis.buddhist.util.CommonUtil;
import com.zhy.http.okhttp.OkHttpUtils;
import com.zhy.http.okhttp.callback.FileCallBack;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

import okhttp3.Call;

public class DownloadDialogFragment extends DialogFragment {


    private static final String TAG = "DownloadDialogFragment";
    private View mView;
    private String mUrl;
    private ProgressBar mProgressBar;
    private int WRITE_EXTERNAL_STORAGE_REQUEST_CODE = 0;
    private String mTitle;
    private String mCover;
    private String mId;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        mView = inflater.inflate(R.layout.dialog_download, container, false);
        //启用窗体的扩展特性。
        getDialog().requestWindowFeature(Window.FEATURE_NO_TITLE);
        getDialog().getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
        getDialog().setCanceledOnTouchOutside(false);
        getDialog().setCancelable(false);
        getDialog().setOnKeyListener(new DialogInterface.OnKeyListener() {
            @Override
            public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
                if (keyCode == KeyEvent.KEYCODE_BACK) {
                    return true;
                }
                return false;
            }
        });
        initView();
        return mView;
    }

    private void initView() {
        mProgressBar = (ProgressBar) mView.findViewById(R.id.pb_progressbar);
        Bundle arguments = getArguments();
        if (arguments != null) {
            mTitle = arguments.getString(C.IntentKey.MESSAGE_INTENT_KEY);
            mUrl = arguments.getString(C.IntentKey.MESSAGE_INTENT_KEY2);
            mCover = arguments.getString(C.IntentKey.MESSAGE_INTENT_KEY3);
            mId = arguments.getString(C.IntentKey.MESSAGE_INTENT_KEY4);
            if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE)
                    != PackageManager.PERMISSION_GRANTED) {
                //申请WRITE_EXTERNAL_STORAGE权限
                requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                        WRITE_EXTERNAL_STORAGE_REQUEST_CODE);
            } else {
                downLoad(mUrl);
            }
        }
    }

    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        return super.onCreateDialog(savedInstanceState);
    }

    private void downLoad(String url) {

        final String name = url.substring(url.lastIndexOf("/") + 1, url.lastIndexOf("."));

        if(CommonUtil.isNetworkAvailable(getActivity())) {

            OkHttpUtils
                    .get()
                    .url(url)
                    .build()
                    .execute(new FileCallBack(Environment.getExternalStorageDirectory().getAbsolutePath(), name + ".zip")//
                    {
                        @Override
                        public void onError(Call call, Exception e, int id) {
                            Log.e(TAG, "onError :" + e.getMessage());
                        }

                        @Override
                        public void onResponse(File file, int id) {
                            Log.e(TAG, "onResponse :" + file.getAbsolutePath());
                            unZip(file, name);
                            dismiss();
                        }

                        @Override
                        public void inProgress(float progress, long total, int id) {
                            mProgressBar.setProgress((int) (100 * progress));
                        }
                    });
        }else{
            Toast.makeText(getActivity(), "請檢查網絡狀態!", Toast.LENGTH_SHORT).show();
        }

    }

    public void unZip(File file, String name) {

        String path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + getActivity().getPackageName() + "/file/unzip/" + name + "/";
        //创建文件夹
        File filePath = new File(path);
        if (!filePath.exists())
            filePath.mkdirs();
        try {
            upZipFile(file, path);
        } catch (IOException e) {
            e.printStackTrace();
        }

        Book book = new Book();
        book.setName(mTitle);
        book.setPath(path);
        book.setCover(mCover);
        book.setContentId(mId);
        BookDaoOpen.insertData(getActivity(), book);

        toReadBook(book);
        //Toast.makeText(getActivity(), "解压完成", Toast.LENGTH_SHORT).show();
    }

    private void toReadBook(Book book) {
        Intent intent = new Intent(getActivity(), ReadActivity.class);
        intent.putExtra(C.IntentKey.MESSAGE_INTENT_KEY, book);
        startActivity(intent);
    }

    /**
     * 解压缩
     * 将zipFile文件解压到folderPath目录下.
     *
     * @param zipFile    zip文件
     * @param folderPath 解压到的地址
     * @throws IOException
     */
    private void upZipFile(File zipFile, String folderPath) throws IOException {
        ZipFile zfile = new ZipFile(zipFile);
        Enumeration zList = zfile.entries();
        ZipEntry ze = null;
        byte[] buf = new byte[1024];
        while (zList.hasMoreElements()) {
            ze = (ZipEntry) zList.nextElement();
            if (ze.isDirectory()) {
                Log.d(TAG, "ze.getName() = " + ze.getName());
                String dirstr = folderPath + ze.getName();
                dirstr = new String(dirstr.getBytes("8859_1"), "GB2312");
                Log.d(TAG, "str = " + dirstr);
                File f = new File(dirstr);
                f.mkdir();
                continue;
            }
            Log.d(TAG, "ze.getName() = " + ze.getName());
            OutputStream os = new BufferedOutputStream(new FileOutputStream(getRealFileName(folderPath, ze.getName())));
            InputStream is = new BufferedInputStream(zfile.getInputStream(ze));
            int readLen = 0;
            while ((readLen = is.read(buf, 0, 1024)) != -1) {
                os.write(buf, 0, readLen);
            }
            is.close();
            os.close();
        }
        zfile.close();
    }

    /**
     * 给定根目录，返回一个相对路径所对应的实际文件名.
     *
     * @param baseDir     指定根目录
     * @param absFileName 相对路径名，来自于ZipEntry中的name
     * @return java.io.File 实际的文件
     */
    public File getRealFileName(String baseDir, String absFileName) {
        String[] dirs = absFileName.split("/");
        File ret = new File(baseDir, absFileName);
        String substr = null;
        if (dirs.length > 1) {
            for (int i = 0; i < dirs.length - 1; i++) {
                substr = dirs[i];
                try {
                    substr = new String(substr.getBytes("8859_1"), "GB2312");
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
                ret = new File(ret, substr);

            }
            Log.d(TAG, "1ret = " + ret);
            if (!ret.exists())
                ret.mkdirs();
            substr = dirs[dirs.length - 1];
            try {
                substr = new String(substr.getBytes("8859_1"), "GB2312");
                Log.d(TAG, "substr = " + substr);
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            ret = new File(ret, substr);
            Log.d(TAG, "2ret = " + ret);
            return ret;
        }
        return ret;
    }

    public void install(File file) {
        //        Intent intent = new Intent();
        //        intent.setAction(Intent.ACTION_VIEW);
        //        intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
        //        startActivity(intent);


        Intent intent = new Intent(Intent.ACTION_VIEW);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            Uri contentUri = FileProvider.getUriForFile(getActivity(), BuildConfig.APPLICATION_ID + ".fileprovider", file);
            intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
        } else {
            intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        }
        getActivity().startActivity(intent);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        doNext(requestCode, grantResults);
    }

    private void doNext(int requestCode, int[] grantResults) {
        if (requestCode == WRITE_EXTERNAL_STORAGE_REQUEST_CODE) {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Permission Granted
                downLoad(mUrl);
            } else {
                // Permission Denied
            }
        }
    }
}